#!/usr/bin/python
#
# Copyright (c) 2011 by Stefan Schliebs <sschliebs@gmail.com>
# Licenced under the GNU General Public License v3 (GPLv3)
#
# Modifications Copyright (c) 2012 by John Graves
#
################################################################
################################################################

"""
Converts OpenOffice Impress files (extension .odp) into a series of
PNG image files (one for each slide). The images are numbered sequentially.
The script makes use of some function offered by the openoffice-python
library <http://openoffice-python.origo.ethz.ch/>.

Usage: odp2png.py [options] ODP-FILES

Options:
  -h, --help   show this help message and exit
  --host=HOST  server address to listen on (default: localhost, use '0.0.0.0'
               for listening on all IPv4 addresses)
  --port=PORT  port to listen on (default: 2002)
"""

################################################################
################################################################

from converter import ConverterError

from openoffice.oooserver import start, stop
from openoffice.interact import Desktop
from openoffice.officehelper import BootstrapException
from unohelper import systemPathToFileUrl
from com.sun.star.beans import PropertyValue

import optparse
import os
import sys

################################################################
################################################################

# FIXME: the prints to stderr should probably go to a log file

def export2png(file_list, desktop, tempDir):
    """
    Exports a list of ODP files into a series of slides.

    The function connects to the given OOo desktop instance.
    """
    
    # determine the output properties for the slide export
    out_props = (
        PropertyValue("FilterName", 0, "impress_png_Export", 0), # we need PNG files
        PropertyValue("Overwrite", 0, True, 0),                  # we overwrite existing files 
        )

    # loop over all files in the list
    for f in file_list:
        print "Processing file %s..." % f

        # check if the file exists
        if not os.path.exists(f):
            print >> sys.stderr, "  Could not find file %s. Skipping..." % f
            continue
        
        # check for the right file extension
        if not f.lower().endswith(".odp"):
            print >> sys.stderr, "  File %s does not seem an ODP file. Skipping..." % f
            continue

        # convert the file name into an URL
        url = os.path.expanduser(f)
        url = os.path.abspath(url)
        url = systemPathToFileUrl(url)

        # determine the number of pages in the document
        try:
            document = desktop.loadComponentFromURL(url ,"_blank", 0, ())
            nb_pages = document.getDrawPages().getCount()
            document.close(True)
        except Exception, e:
            print >> sys.stderr, "Could not determine number of pages in the " \
                  "document. Skipping..."
            continue

        # draw each slide at a time
        for i in xrange(nb_pages):
            print "  Saving slide %d..." % i
            
            document = desktop.loadComponentFromURL(url ,"_blank", 0, ())

            # delete all slides but the one we want to draw
            _rm_page_nb = 0
            for j in xrange(nb_pages):
                if i==j:
                    _rm_page_nb = 1
                else:
                    page = document.getDrawPages().getByIndex(_rm_page_nb)
                    document.getDrawPages().remove(page) 

            # determine file name where to save the slide to
            fname = tempDir + "/Slide" + ("%d.png" % i)
            fname = os.path.expanduser(fname)
            fname = os.path.abspath(fname)
            fname = systemPathToFileUrl(fname)
            document.storeToURL(fname, out_props)
            document.close(True)

def runparse(opts,args):

    # nothing to do, if no files were passed
    if not len(args) >= 1:
        parser.error('No ODP files specified!')
    
    try:
        # start an OOo instance
        start(host=opts.host, port=opts.port)

        # connect to the OOo instance listening on host/port
        desktop = Desktop(host=opts.host, port=opts.port)._desktop

        # export the files to PNG
        export2png(args, desktop, '/tmp')
    except BootstrapException:
        print >> sys.stderr, 'Could not contact OOo instance. Perhaps it was not running?'
    except Exception, e:
        # something unexpected happened
        print >> sys.stderr, "An unexpected error occurred: "
        print >> sys.stderr, e
    finally:
        # ALWAYS stop the OOo instance AND delete all references to it (in
        # our case the desktop variable)
        stop(host=opts.host, port=opts.port)
        if vars().has_key('desktop'):
            del desktop

def runparseNoOpts(args, tempDir):

    # nothing to do, if no files were passed
    if not len(args) >= 1:
        parser.error('No ODP files specified!')
    
    try:
        # start an OOo instance
        start(host='localhost', port=2002)

        # connect to the OOo instance listening on host/port
        desktop = Desktop(host='localhost', port=2002)._desktop

        # export the files to PNG
        export2png(args, desktop, tempDir)
    except BootstrapException:
        print >> sys.stderr, 'Could not contact OOo instance. Perhaps it was not running?'
    except Exception, e:
        # something unexpected happened
        print >> sys.stderr, "An unexpected error occurred: "
        print >> sys.stderr, e
    finally:
        # ALWAYS stop the OOo instance AND delete all references to it (in
        # our case the desktop variable)
        stop(host='localhost', port=2002)
        if vars().has_key('desktop'):
            del desktop

if __name__ == '__main__':

    # process the command line parameters
    parser = optparse.OptionParser('%prog [options] ODP-FILES')
    parser.add_option('--host',  default='localhost',
                      help="server address to listen on (default: %default, "
                           "use '0.0.0.0' for listening on all IPv4 addresses)")
    parser.add_option('--port',  default=2002, type=int,
                      help="port to listen on (default: %default)")
    opts, args = parser.parse_args()
    runparse(opts, args)

